﻿/*******************************************************
 * 作    者：罗敏贵
 * 运行环境：.NET Framework 4.8.3928.0
 * 操作系统：Microsoft Windows NT 6.1.7601 Service Pack 1
 * 版 本号：4.0.30319.42000
 * 文件说明：
 * 历史记录：
 *     创建文件 罗敏贵 2021-12-29
 *
*******************************************************/
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace System {
    public class ServiceLocator {
        private static IServiceProvider _serviceProvider { get; set; }
        public static void SetServices(IServiceProvider services) {
            if(services==null) {
                throw new ArgumentNullException(nameof(services));
            }
            _serviceProvider=services;
        }
        public static IServiceProvider GetServiceProvider() {
            var accessor = _serviceProvider.GetService<IHttpContextAccessor>();
            var context = accessor.HttpContext;
            return context?.RequestServices??_serviceProvider;
        }
        public static T Resolve<T>() where T : class {
            return (T)GetServiceProvider().GetRequiredService(typeof(T));
        }
        public static object Resolve(Type type) {
            return GetServiceProvider().GetRequiredService(type);
        }
        public static IEnumerable<T> ResolveAll<T>() {
            return (IEnumerable<T>)GetServiceProvider().GetServices(typeof(T));
        }
        public static object ResolveUnregistered(Type type) {
            Exception innerException = null;
            foreach(var constructor in type.GetConstructors()) {
                try {
                    var parameters = constructor.GetParameters().Select(parameter => {
                        var service = Resolve(parameter.ParameterType);
                        if(service==null)
                            throw new Exception("Unknown dependency");
                        return service;
                    });
                    return Activator.CreateInstance(type,parameters.ToArray());
                } catch(Exception ex) {
                    innerException=ex;
                }
            }
            throw new Exception("No constructor was found that had all the dependencies satisfied.",innerException);
        }

        public static string MapPath(string path) {
            var _hostEnviroment = Resolve<Microsoft.AspNetCore.Hosting.IHostingEnvironment>();
            return Path.Combine(_hostEnviroment.ContentRootPath,path);
        }
    }
}